package com.soxing.braindata.service.manager;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.soxing.braindata.dao.domain.request.SearchRequest;
import com.soxing.braindata.dao.domain.vo.TinyResearch;
import com.soxing.braindata.dao.entity.Equipment;
import com.soxing.braindata.dao.entity.Role;
import com.soxing.braindata.dao.entity.Site;
import com.soxing.braindata.dao.entity.UserInfoExt;
import com.soxing.braindata.dao.service.IEquipmentService;
import com.soxing.braindata.dao.service.IRoleService;
import com.soxing.braindata.dao.service.IUserInfoExtService;
import com.soxing.braindata.dao.service.IUserRoleService;
import com.soxing.braindata.domain.request.EquipmentSearchRequest;
import com.soxing.braindata.domain.vo.EquipmentVo;
import com.soxing.common.utils.response.MyPage;
import com.soxing.common.utils.response.WebResponse;
import com.soxing.common.utils.util.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author :durango
 * @date :2022/6/11 15:03
 * @description 设备管理服务实现
 */
@Service
public class EquipmentManagerImpl extends AbstractManager<Equipment> implements IEquipmentManager {

    @Resource
    private IEquipmentService equipmentService;
    @Resource
    private ISiteManager siteManager;

    @Resource
    private IUserInfoExtService userInfoExtService;

    @Resource
    private IRoleService roleService;

    @Override
    public IService<Equipment> getService() {
        return equipmentService;
    }

    @Override
    public LambdaQueryWrapper<Equipment> wrapSearchRequest(SearchRequest request) {
        EquipmentSearchRequest searchRequest = (EquipmentSearchRequest) request;
        if (request == null) {
            searchRequest = new EquipmentSearchRequest();
        }
        Equipment obj = ObjectMapper.map(searchRequest, Equipment.class);
        LambdaQueryWrapper<Equipment> queryWrapper = new LambdaQueryWrapper<>(obj);
        if (StringUtils.isNotBlank(searchRequest.getEquipmentName())) {
            obj.setEquipmentName(null);
            queryWrapper.like(Equipment::getEquipmentName, searchRequest.getEquipmentName());
        }
        return queryWrapper;
    }

    @Override
    public WebResponse<EquipmentVo> getVoById(Integer id) {
        Equipment equipment = equipmentService.getById(id);
        if (equipment == null) {
            return WebResponse.success();
        }
        List<Site> siteList = siteManager.getSiteBysitePkIds(Sets.newHashSet(equipment.getSitePkId()));
        Map<String, Site> siteMap = siteList.stream().collect(Collectors.toMap(Site::getSitePkId, Function.identity(), (a, b) -> b));
        Site site = siteMap.get(equipment.getSitePkId());

        EquipmentVo equipmentVo = ObjectMapper.map(equipment, EquipmentVo.class);
        if (site != null) {
            equipmentVo.setSiteName(site.getSiteName());
        }
        return WebResponse.success(equipmentVo);
    }

    @Override
    public WebResponse<MyPage<EquipmentVo>> search(EquipmentSearchRequest request) {
        WebResponse<MyPage<Equipment>> response = super.search(request);
        MyPage<Equipment> res = response.getData();
        List<Equipment> records = res.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return WebResponse.success(new MyPage<>(1, 0, 0, new ArrayList<>()));
        }
        Set<String> sitePkIdSet = records.stream().map(Equipment::getSitePkId).collect(Collectors.toSet());
        List<Site> siteList = siteManager.getSiteBysitePkIds(sitePkIdSet);
        Map<String, Site> siteMap = siteList.stream().collect(Collectors.toMap(Site::getSitePkId, Function.identity(), (a, b) -> b));

        List<EquipmentVo> equipmentVoList = Lists.newArrayList();
        records.forEach(equipment -> {
            EquipmentVo equipmentVo = ObjectMapper.map(equipment, EquipmentVo.class);
            Site site = siteMap.get(equipment.getSitePkId());
            if (site != null) {
                equipmentVo.setSiteName(site.getSiteName());
            }
            equipmentVoList.add(equipmentVo);
        });
        return WebResponse.success(new MyPage<EquipmentVo>(request.getPageNum(), res.getPages(), res.getTotal(), equipmentVoList));
    }


    //如果是队列管理员或者系统总管理员，返回这个。
    public WebResponse<MyPage<EquipmentVo>> getEquipmentByUser(String userNum,int pageSize,int pageNum)
    {
        UserInfoExt userInfoExt = userInfoExtService.getOne(new LambdaQueryWrapper<UserInfoExt>().eq(UserInfoExt::getUserNum,userNum));
        Page<Equipment> page = new Page<>(pageNum, pageSize);
        if(userInfoExt.getUserType()==0)
        {
            IPage<Equipment> res = equipmentService.page(page);

            //下面一大段代码都是为了让equipment 带上中心名称
            List<Equipment> records = res.getRecords();
            if (CollectionUtils.isEmpty(records)) {
                return WebResponse.success(new MyPage<>(1, 0, 0, new ArrayList<>()));
            }
            Set<String> sitePkIdSet = records.stream().map(Equipment::getSitePkId).collect(Collectors.toSet());
            List<Site> siteList = siteManager.getSiteBysitePkIds(sitePkIdSet);
            Map<String, Site> siteMap = siteList.stream().collect(Collectors.toMap(Site::getSitePkId, Function.identity(), (a, b) -> b));

            List<EquipmentVo> equipmentVoList = Lists.newArrayList();
            records.forEach(equipment -> {
                EquipmentVo equipmentVo = ObjectMapper.map(equipment, EquipmentVo.class);
                Site site = siteMap.get(equipment.getSitePkId());
                if (site != null) {
                    equipmentVo.setSiteName(site.getSiteName());
                }
                equipmentVoList.add(equipmentVo);
            });

            return WebResponse.success(new MyPage<>(pageNum, res.getPages(), res.getTotal(),equipmentVoList));
        }
        else
        {
            //# 这里的逻辑也还是有点问题，感觉上，因为一个课题管理员很可能属于很多个分中心，或者下面直接不挂分中心，到时候数据库里的中心字段可能还要规整一下。
            List<Role> roleList = roleService.list(new LambdaQueryWrapper<Role>().eq(Role::getUserPkId,userNum));
            Set<String> sitePkidSet = roleList.stream().map(
                    Role::getSitePkId
            ).collect(Collectors.toSet());

            IPage<Equipment> res = equipmentService.page(page,new LambdaQueryWrapper<Equipment>().in(Equipment::getSitePkId,sitePkidSet));

            List<Equipment> records = res.getRecords();
            if (CollectionUtils.isEmpty(records)) {
                return WebResponse.success(new MyPage<>(1, 0, 0, new ArrayList<>()));
            }
            Set<String> sitePkIdSet = records.stream().map(Equipment::getSitePkId).collect(Collectors.toSet());
            List<Site> siteList = siteManager.getSiteBysitePkIds(sitePkIdSet);
            Map<String, Site> siteMap = siteList.stream().collect(Collectors.toMap(Site::getSitePkId, Function.identity(), (a, b) -> b));

            List<EquipmentVo> equipmentVoList = Lists.newArrayList();
            records.forEach(equipment -> {
                EquipmentVo equipmentVo = ObjectMapper.map(equipment, EquipmentVo.class);
                Site site = siteMap.get(equipment.getSitePkId());
                if (site != null) {
                    equipmentVo.setSiteName(site.getSiteName());
                }
                equipmentVoList.add(equipmentVo);
            });

            return WebResponse.success(new MyPage<>(pageNum, res.getPages(), res.getTotal(), equipmentVoList));
        }
    }
}

